#ifndef AVALON_SINGLETON_HPP
#define AVALON_SINGLETON_HPP
#include <boost/utility.hpp>
#include <boost/thread/once.hpp>
#include <boost/scoped_ptr.hpp>

namespace Avalon {

  /*! \class Singleton
   *  \brief Implements the Singleton pattern.
   */
  template<typename T>
  class Singleton : private boost::noncopyable {
    public:
      ~Singleton() {}

      //! Returns the singleton instance.
      static T& GetInstance() {
        boost::call_once(ConstructSingleton, m_onceFlag);
        return *m_singleton;
      }

    private:
      static boost::scoped_ptr<T> m_singleton;
      static boost::once_flag m_onceFlag;

      static void ConstructSingleton() {
        m_singleton.reset(new T());
      }
  };

  template<typename T> boost::scoped_ptr<T> Singleton<T>::m_singleton;
  template<typename T> boost::once_flag Singleton<T>::m_onceFlag =
    BOOST_ONCE_INIT;
}

#endif // AVALON_SINGLETON_HPP
